package com.dcy.daily.common.configuration.redis;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.spring.cache.CacheConfig;
import org.redisson.spring.cache.RedissonSpringCacheManager;
import org.redisson.spring.starter.RedissonProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * redisson配置信息，配置CacheManger，SpringBoot Cache会使用该CacheManger。
 *
 * @author duanchunyu
 * @version 1.0.0
 * @createTime 2021年07月01日 15:02:00
 */
@Configuration
@ConditionalOnProperty(prefix = "spring.redis",name = "enable",havingValue = "true")
@EnableConfigurationProperties({RedissonProperties.class})
@EnableCaching
public class RedissonConfig {

    @Autowired
    private ApplicationContext ctx;
    @Autowired
    private RedissonProperties redissonProperties;

    @Bean(destroyMethod = "shutdown")
    public RedissonClient redisson() throws IOException{
        Config config = null;
        if(this.redissonProperties.getFile() != null){
            Resource resource = this.ctx.getResource(this.redissonProperties.getFile());
            InputStream is = resource.getInputStream();
            config = Config.fromYAML(is);
        }
        return Redisson.create(config);
    }

    /**
     *
     * Cache中key的生成策略
     * 使用方法@Cacheable(value = "books2",keyGenerator = "keyGenerator")
     *
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(target.getClass().getName());
            stringBuffer.append("-");
            stringBuffer.append(method.getName());
            stringBuffer.append("-");
            stringBuffer.append(StringUtils.arrayToDelimitedString(params,"-"));
            return stringBuffer.toString();
        };
    }

    /**
     * 声明一个CacheManager，具体的缓存存储。
     *
     * @param redissonClient
     * @return
     */
    @Bean
    CacheManager cacheManager(RedissonClient redissonClient) {
        Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
        // 创建一个名称为"testMap"的缓存，过期时间ttl为10s，同时最长空闲时间maxIdleTime为15分钟。
        config.put("CacheKey", new CacheConfig(10 * 1000, 12 * 60 * 1000));
        config.put("PerCacheKey", new CacheConfig(0, 0));
        return new RedissonSpringCacheManager(redissonClient, config);
    }

}
